package com.bobochang.warehouse.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bobochang.warehouse.dto.ContractTypeNumberDto;
import com.bobochang.warehouse.dto.EginnerContractDto;
import com.bobochang.warehouse.dto.MaterialNumDto;
import com.bobochang.warehouse.entity.*;
import com.bobochang.warehouse.mapper.ConstructionAndContractMapper;
import com.bobochang.warehouse.mapper.ContractMapper;
import com.bobochang.warehouse.mapper.DailyConstructionMapper;
import com.bobochang.warehouse.mapper.FaceModelMapper;
import com.bobochang.warehouse.page.Page;
import com.bobochang.warehouse.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author bobochang
 * @Description
 * @Date 2023/9/19 - 10:55
 */
@Service
@Slf4j
public class ContractServiceImpl extends ServiceImpl<ContractMapper, Contract>
        implements ContractService {

    @Autowired
    private ContractMapper contractMapper;

    @Value("${file.upload-path}")
    private String accessPath;
    
    @Autowired
    private ContractEginnerService contractEginnerService;

    @Autowired
    private CustomerService customerService;
    
    @Autowired
    private ProductService productService;
    
    @Autowired
    private ContractRatioService contractRatioService;

    @Autowired
    private ConstructionAndContractMapper constructionAndContractMapper;

    @Autowired
    //private DailyConstructionService dailyConstructionService;
    private DailyConstructionMapper dailyConstructionMapper;

    @Override
    public Contract findContractById(Integer contractId) {
        return contractMapper.findContractById(contractId);
    }

    @Override
    public Page queryContractPage(Page page, Contract contract) {
        // 查询合同总行数
        int contractCount = contractMapper.selectContractCount(contract);

        // 分页查询合同
        List<Contract> contractList = contractMapper.selectContractPage(page, contract);

        // 将查询到的总行数和当前页数据组装到 Page 对象
        page.setTotalNum(contractCount);
        page.setResultList(contractList);
        return page;
    }

    @Override
    public Result saveContract(EginnerContractDto contract) {
        contract.setContractState("0");


        // 根据合同id查询合同
        Contract oldContract = contractMapper.findContractByName(contract.getContractName());
        if (oldContract != null) {
            return Result.err(Result.CODE_ERR_BUSINESS, "该合同已存在！");
        }
        if(contract.getCustomerId() == -1){
            contract.setCustomerId(null);
        }

        if(Stream.of("0","1","3","4").collect(Collectors.toList()).contains(contract.getIfPurchase())){
            contract.setMaterials("[]");
        }
        // 合同不存在 添加合同
        contractMapper.insertContract(contract);
        // 添加客户关系
        customerService.addCustomerAndContract(contract.getContractId(), contract.getCustomerIds());

        //施工合同，添加施工类型数据
        if(contract.getIfPurchase().equals("4")){
            Integer id = contract.getContractId();
            for (ContractTypeNumberDto ctnd : contract.getSelectedType()) {
                constructionAndContractMapper.insert(new ConstructionAndContract
                        (id,ctnd.getId(),ctnd.getNumber(),ctnd.getUnitPrice(),ctnd.getUnitId()));
            }


        }
        
        return Result.ok("添加合同成功");
    }

    @Override
    public int updateContractState(Contract contract) {
        // 根据合同 id 修改合同状态
        return contractMapper.updateContractState(contract);
    }

    @Override
    public Result updateContractById(Contract contract) {
        if (contract.getCustomerId() == null) {
            log.info(String.valueOf(contract.getOtherCustomer()));
            contract.setCustomerId(null);
        }else{
            log.info(String.valueOf(contract.getCustomerId()));
            contract.setOtherCustomer(null);
        }
        contract.setFiles(accessPath+contract.getFiles());
        // 根据合同 id 修改合同昵称
        int i = contractMapper.updateContractById(contract);
        // 修改合同客户关系
        contractMapper.deleteCustomerAndContract(contract.getContractId());
        customerService.addCustomerAndContract(contract.getContractId(), contract.getCustomerIds());

        if (i > 0) {
            return Result.ok("修改成功");
        }
        return Result.err(Result.CODE_ERR_BUSINESS, "修改失败");
    }

    @Override
    public int searchContractCount(Contract contract) {
        return contractMapper.selectContractCount(contract);
    }

    @Override
    public Contract findContractById(int contractId) {
        return contractMapper.findContractById(contractId);
    }

    @Override
    public Result selectAllContract() {
        List<Contract> contractList = contractMapper.selectAllContract();
        return Result.ok(contractList);
    }

    @Override
    public int updateContractIfPurchase(Contract contract) {
        
        return contractMapper.updateContractIfPurchase(contract);
    }

    @Override
    public Result getNeedMaterialNum(MaterialNumDto materialNumDto) {
        MaterialNumDto numDto = contractMapper.getNeedMaterialNum(materialNumDto);
        return Result.ok(numDto);
    }

    @Override
    public void saveContractEginner(EginnerContractDto contractDto) {
        System.out.println(contractDto.getSigningDate());
        if(contractDto.getIfPurchase() == null || contractDto.getIfPurchase().equals("")){
            contractDto.setIfPurchase("3");
        }
        contractDto.setCustomerId(-1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d日");
        LocalDate localDate = LocalDate.parse(contractDto.getSigningDate(), formatter);

        String formattedDate = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        contractDto.setSigningDate(formattedDate);

        List<Product> productList = productService.queryAllProduct();
        
        try {
            saveContract(contractDto);
            int contractId = contractDto.getContractId();
            for (ContractEginner contractEginner : contractDto.getContractEginnerList()){
                contractEginner.setContractId(contractDto.getContractId());
                for (Product product : productList){
                    if (contractEginner.getProductName().contains(product.getProductName())){
                        contractEginner.setProductId(product.getProductId());
                        break;
                    }
                }
                contractEginnerService.saveContractEginner(contractEginner);
            }

            for (List<ContractRatio> list : contractDto.getRatioLists()){
                for (ContractRatio contractRatio: list){
                    contractRatio.setId(null);
                    contractRatio.setContractId(contractDto.getContractId());
                    contractRatioService.saveContractRatio(contractRatio);
                }
            }

            List<Integer> productIdList = contractRatioService.selectProductByContractId(contractDto.getContractId());
            for (Integer productId : productIdList){
                ContractEginner contractEginner = contractEginnerService.selectByProductAndContract(productId, contractDto.getContractId());
                contractEginner.setIfRatio("1");
                contractEginnerService.updateIfRatioById(contractEginner);
            }
        }catch (Exception e){
            log.info(String.valueOf(e));
        }

    }

    @Override
    public List<Contract> findAllContract(Contract contract) {
        LambdaQueryWrapper<Contract> queryWrapper = new LambdaQueryWrapper<Contract>()
                .like(contract.getContractName() != null, Contract::getContractName, contract.getContractName());
        List<Contract> contractList = baseMapper.selectList(queryWrapper);
        return contractList;
    }

    @Override
    @Transactional
    public Result updateConstructionContractById(EginnerContractDto contract) {
        // 旧施工类型关系
        List<ConstructionAndContract> oldConstructionAndContracts = constructionAndContractMapper.selectList(new LambdaQueryWrapper<ConstructionAndContract>().eq(ConstructionAndContract::getContractId, contract.getContractId()));
        Contract oldContract = contractMapper.findContractById(contract.getContractId());
        // 查询修改是否产生违规数据
        // 施工明细
        List<DailyConstruction> dailyConstructions = dailyConstructionMapper.selectList(new LambdaQueryWrapper<DailyConstruction>().eq(DailyConstruction::getContractId, contract.getContractId()));
        int i = 0;
        for(DailyConstruction dc: dailyConstructions) {
            if(dc.getDate().compareTo(contract.getStartTime()) < 0 || dc.getDate().compareTo(contract.getEndTime()) > 0){
                return Result.err(Result.CODE_ERR_BUSINESS,"修改导致施工明细上报时间存在超时");
            }
        }
        if(dailyConstructions.stream()
                .map(DailyConstruction::getConstructionTypeId)
                .anyMatch(id ->
                        contract.getSelectedType().stream()
                        .map(ContractTypeNumberDto::getId)
                        .noneMatch(e -> e.equals(id))
                )
        ){
            return Result.err(Result.CODE_ERR_BUSINESS,"修改导致施工明细上报施工类型存在错误");
        }

        oldContract.setContractName(contract.getContractName());
        oldContract.setStartTime(contract.getStartTime());
        oldContract.setEndTime(contract.getEndTime());
        oldContract.setWorkRegion(contract.getWorkRegion());
        oldContract.setProjectName(contract.getProjectName());
        oldContract.setOtherCustomer(contract.getOtherCustomer());
        oldContract.setCompany(contract.getCompany());
        oldContract.setSigningAddress(contract.getSigningAddress());
        oldContract.setSigningDate(contract.getSigningDate());
        contractMapper.updateContractById(oldContract);
        //更新施工类型数据
        constructionAndContractMapper.delete(new LambdaQueryWrapper<ConstructionAndContract>().eq(ConstructionAndContract::getContractId, contract.getContractId()));
        for (ContractTypeNumberDto ctnd : contract.getSelectedType()) {
            constructionAndContractMapper.insert(new ConstructionAndContract
                    (contract.getContractId() ,ctnd.getId(),ctnd.getNumber(),ctnd.getUnitPrice(),ctnd.getUnitId()));
        }
        return Result.ok();
    }
}
